﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Keepo.Models;
using Infrastructure.Data;
using AlbumDesigner.Models.Enums;

namespace AlbumDesigner.Helpers
{
    public class AlbumPagesHelper
    {
        // Currently Maximal spine is 10mm.
        // 10mm = 0.3937
        // 6mm = 0.23622
        // 4mm = 0.15748

        static public int InchesToPixels(double inchValue)
        {
            return InchesToPixels((float)inchValue);
        }

        static public int InchesToPixels(float inchValue)
        {
            return Convert.ToInt32(Math.Floor(inchValue * 300));
        }

        static public float MMToInches(float mmValue)
        {
            return mmValue / (float)25.4;
        }

        static public int MMToPixels(float mmValue)
        {
            var inchesValue = MMToInches(mmValue);
            var pixValue = InchesToPixels(inchesValue);
            return pixValue;
        }

        static public int PageNumByPageId(int pageId)
        {
            using (var db = new AlbumContext())
            {
                var page = db.AlbumPages.FirstOrDefault(p => p.AlbumPageId == pageId);

                // Cover has no page number
                if (page.AlbumSection.AlbumSectionTypeId == (int)AlbumSectionTypeEnum.Cover)
                {
                    return -1;
                }

                int pageNum = SectionFirstPageNum(page.AlbumSectionId);

                var numSingles = page.AlbumSection.AlbumPages.Count(p => p.IsSingle && p.SectionPageIdx < page.SectionPageIdx);
                var numDoubles = page.AlbumSection.AlbumPages.Count(p => !p.IsSingle && p.SectionPageIdx < page.SectionPageIdx);

                pageNum += numSingles + 2 * numDoubles;

                return pageNum;
            }
        }

        static public int SectionFirstPageNum(int sectionId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var section = repository.GetByKey<AlbumSection>(sectionId);

                // If it's a cover section return 0 for ordering pages, else start from 1
                if (section.isCoverSection())
                {
                    return 0;
                }
                else
                {
                    // Ignore cover section when counting pages
                    var sections = repository.Find<AlbumSection>(s => s.SectionIdx < section.SectionIdx && s.AlbumId == section.AlbumId &&
                        s.AlbumSectionTypeId != (int)AlbumSectionTypeEnum.Cover);

                    var numPages = sections.Sum(s => s.PagesCount);

                    int pageNum = 1 + numPages;

                    return pageNum;
                }
            }
        }

        static public int NumOfPagesInAlbum(int albumId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                // Ignore cover section when counting pages
                var sections = repository.Find<AlbumSection>(s => s.AlbumId == albumId &&
                    s.AlbumSectionTypeId != (int)AlbumSectionTypeEnum.Cover);

                var numPages = sections.Sum(s => s.PagesCount);

                return numPages;
            }
        }

        static public bool MoveAlbumPage(int srcPageId, int dstPageId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var srcPage = repository.GetByKey<AlbumPage>(srcPageId);
                var dstPage = repository.GetByKey<AlbumPage>(dstPageId);

                // Case target page doesn't exists
                if (srcPage == null || dstPage == null)
                {
                    return false;
                }

                // Case trying to replate between single and double
                if (srcPage.IsSingle || dstPage.IsSingle)
                {
                    return false;
                }

                // Case moving bewtween different sections
                if (srcPage.AlbumSectionId != dstPage.AlbumSectionId)
                {
                    return false;
                }


                int srcPageIdx = srcPage.SectionPageIdx;
                int dstPageIdx = dstPage.SectionPageIdx;

                if (srcPageIdx < dstPageIdx)
                {
                    var pages = repository.Find<AlbumPage>(p => p.AlbumSectionId == srcPage.AlbumSectionId && p.SectionPageIdx > srcPageIdx && p.SectionPageIdx <= dstPageIdx);
                    pages.ToList().ForEach(p => p.SectionPageIdx = p.SectionPageIdx - 1);
                }
                else
                {
                    var pages = repository.Find<AlbumPage>(p => p.AlbumSectionId == srcPage.AlbumSectionId && p.SectionPageIdx < srcPageIdx && p.SectionPageIdx >= dstPageIdx);
                    pages.ToList().ForEach(p => p.SectionPageIdx = p.SectionPageIdx + 1);
                }

                srcPage.SectionPageIdx = dstPageIdx;

                //set "HasRender" field of this Album to false (to mark the album as "changed" and allow rendering it again)
                srcPage.AlbumSection.Album.HasRender = false;

                repository.UnitOfWork.SaveChanges();
            }

            return true;
        }

    }
}